package com.ohos.blurredgridmenu;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

/**
 * A circle progressBar which can change with the real loading progress ratio.
 */
public class LoadingCircleProgressView extends Component implements Component.DrawTask {

    private float currentProgressRatio = 0.6f;

    private int defaultSize = 80;
    private int defaultStrokeWidth = 10;
    private int strokeWidth = defaultStrokeWidth;
    private int radius = (defaultSize) / 2 - defaultStrokeWidth;

    private Paint bgPaint;
    private RectFloat rectF;
    private Paint progressPaint;

    private int progressBgColor = Color.BLACK.getValue();
    private int progressColor = Color.WHITE.getValue();

    public LoadingCircleProgressView(Context context) {
        this(context, null);
    }

    public LoadingCircleProgressView(Context context, AttrSet attrs) {
        this(context, attrs, 0);
    }

    public LoadingCircleProgressView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        rectF = new RectFloat();

        bgPaint = new Paint();
        bgPaint.setStyle(Paint.Style.STROKE_STYLE);
        bgPaint.setStrokeWidth(defaultStrokeWidth);
        progressPaint = new Paint(bgPaint);

        setupPaintColor();
    }

    private void setupPaintColor() {
        progressBgColor = 0XAA000000 | progressBgColor;
        progressColor = 0XEE000000 | progressColor;
        bgPaint.setColor(new Color(progressBgColor));
        progressPaint.setColor(new Color(progressColor));

        addDrawTask(this);
    }

    /**
     * onEstimateSize
     *
     * @param widthMeasureSpec widthMeasureSpec
     * @param heightMeasureSpec heightMeasureSpec
     * @return boolean
     */
    protected boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.NOT_EXCEED) {
            width = Math.max(width, defaultSize);
        } else {
            width = defaultSize;
        }
        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.NOT_EXCEED) {
            height = Math.max(height, defaultSize);
        } else {
            height = defaultSize;
        }
        setEstimatedSize(width, height);

        width = Math.min(width, height);
        height = width;
        strokeWidth = Math.min(width / 5, defaultStrokeWidth);
        radius = (width - strokeWidth) / 2;
        return false;
    }

    public void setCurrentProgressRatio(float currentProgressRatio) {
        if (currentProgressRatio < 0.0f) {
            currentProgressRatio = 0.f;
        }
        if (currentProgressRatio > 1.f) {
            currentProgressRatio = 1.f;
        }
        this.currentProgressRatio = currentProgressRatio;
        invalidate();
    }

    public void setProgressBgColor(int progressBgColor) {
        this.progressBgColor = progressBgColor;
        setupPaintColor();
        invalidate();
    }

    public void setProgressColor(int progressColor) {
        this.progressColor = progressColor;
        setupPaintColor();
        invalidate();
    }

    private int getHalfStrokeWidth() {
        return strokeWidth / 2;
    }

    private int getCurrentDegree() {
        return Math.min(360, (int) (currentProgressRatio * 360));
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        bgPaint.setStrokeWidth(strokeWidth - 2);
        progressPaint.setStrokeWidth(strokeWidth);

        // bg Arc
        rectF.left = getHalfStrokeWidth();
        rectF.top = getHalfStrokeWidth();
        rectF.right = radius * 2 - getHalfStrokeWidth();
        rectF.bottom = radius * 2 - getHalfStrokeWidth();
        canvas.drawArc(rectF, new Arc(0, 360, false), bgPaint);

        // progress Arc
        canvas.rotate(-90, radius, radius);
        canvas.drawArc(rectF, new Arc(0, getCurrentDegree(), false), progressPaint);
    }
}
